package io;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;

public class Communicator
{
	private Socket _socket;
	private ObjectInputStream _input;
	private ObjectOutputStream _output;
	private Thread _receiverThread;
	private ListenerManager _manager;

	public Communicator(Socket socket, ListenerManager manager)
	{
		_socket = socket;
		_manager = manager;
	}
	
	public void execute()
	{
		try
		{
			_output = new ObjectOutputStream(_socket.getOutputStream());
			_input = new ObjectInputStream(_socket.getInputStream());
			
			_receiverThread = new Thread(new Receiver(_input, _manager));
			_receiverThread.start();
			
			if (_manager != null && _manager.getOnLoad() != null)
				_manager.getOnLoad().onEventEDT(null);
			
			try
			{
				_receiverThread.join();
			}
			catch (InterruptedException e)
			{
				e.printStackTrace();
			}
		}
		catch (IOException e)
		{
			System.err.println("Le communicateur distant s'est déconnecté !");
		}
	}
	
	public void Send(Object toSend)
	{
		Thread sender = new Thread(new Sender(_output, toSend));
		sender.start();
	}
	
	public class Receiver implements Runnable
	{
		private ObjectInputStream _input;
		private Object _received;
		private ListenerManager _manager;

		public Receiver(ObjectInputStream input, ListenerManager manager)
		{
			_input = input;
			_manager = manager;
		}

		public void run()
		{
			boolean stop = false;
			
			while(!stop)
			{
				try
				{
					_received = _input.readObject();
					
					// Transmission du message à l'interface
					if (_manager != null && _manager.getOnReceiveMsg() != null) 
						_manager.getOnReceiveMsg().onEventEDT(_received);
				}
				catch (IOException e)
				{
					stop = true;
				}
				catch (ClassNotFoundException e)
				{
					stop = true;
				}
			}
		}
	}

	public class Sender implements Runnable
	{
		private ObjectOutputStream _ouput;
		private Object _received;

		public Sender(ObjectOutputStream output, Object received)
		{
			_ouput = output;
			_received = received;
		}

		public void run()
		{
			try
			{
				_ouput.writeObject(_received);
				_ouput.flush();
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
		}
	}
}